<?php
    /**
    * @name 邮件发送类
    * @copyright tcsos inc
    * @version cooperation v1.0
    */

    class smtp{
        private $smtp_host = '127.0.0.1';
        private $smtp_port = 25;
        private $smtp_auth = true;
        private $smtp_user = '';   
        private $smtp_pass = '';
        private $smtp_name = '';
        private $time_out = 30;   
        private $host_name = 'localhost';
        private $log_file = ''; 
        private $sock = false;
        private $log_open = false;
        private $debug = false;

        //邮件列表
        private $email_list = array(
        '@163.com' => 'http://mail.163.com',
        '@gmail.com' => 'http://mail.google.com',
        '@qq.com' => 'http://mail.qq.com',
        '@sina.com' => 'http://mail.sina.com.cn',
        '@sohu.com' => 'http://mail.sohu.com',
        '@live.com' => 'http://login.live.com/?mkt=zh-CN',
        '@live.cn' => 'http://login.live.com/?mkt=zh-CN',
        '@hotmail.com' => 'http://login.live.com/?mkt=zh-CN',
        '@126.com' => 'http://mail.126.com',
        '@yeah.net' => 'http://mail.yeah.net',
        '@sina.cn' => 'http://mail.sina.com.cn',
        '@sina.com' => 'http://mail.sina.com.cn',
        '@2008.sina.com' => 'http://mail.sina.com.cn',
        '@yahoo.com' => 'http://mail.cn.yahoo.com',
        '@yahoo.cn' => 'http://mail.cn.yahoo.com',
        '@yahoo.com.cn' => 'http://mail.cn.yahoo.com',
        '@139.com' => 'http://mail.10086.cn',
        '@eyou.com' => 'http://www.eyou.com',
        '@189.cn' => 'http://mail.189.cn',
        '@wo.com.cn' => 'http://mail.wo.com.cn',
        '@263.net' => 'http://www.263.net',
        '@x263.net' => 'http://www.263.net',
        '@263.net.cn' => 'http://www.263.net'
        );

        //构造函数
        public function __construct($smtp_config)   
        {   
            $this->smtp_host = $smtp_config['host'];
            $this->smtp_user = $smtp_config['usr'];
            $this->smtp_pass = $smtp_config['pwd'];
            $this->smtp_port = $smtp_config['port'] > 0 ? $smtp_config['port'] : 25;
            $this->smtp_auth = $smtp_config['auth'] ? true:false ;
            $this->smtp_name = $smtp_config['name'] != ''?$smtp_config['name']:'同城搜搜';

            if($this->smtp_host == '' || $this->smtp_user == '' || $this->smtp_pass == ''){
                exit('class smtp __construct exit.');
            }   


        }
        //析构函数
        public function __destruct(){

        }
        /**
        * 获取注册邮件列表
        * 
        */
        public function get_email_list(){
             return $this->email_list;
        }
        
        /**
        * 根据email地址来获取列表地址
        * 
        * @param mixed $email
        */
        public function get_email_site($email){
            if(!is_email($email)){
                return false;
            }
            $email = strtolower($email);
            $temp = explode('@',$email);
            if(empty($temp) || is_null_str($temp[1])){
                return false;
            }
            $site = 'http://www.'.$temp[1];
            if(array_key_exists('@'.$temp[1] , $this->email_list)){
                 $site = $this->email_list['@'.$temp[1]];
            }
            return $site;
        }
        

        /* 发送邮件*/  
        public function send($title , $body , $to , $mailtype = "HTML" , $cc = "", $bcc = "", $additional_headers = "")   
        {   
            
            $mail_from = $this->get_address($this->strip_comment($this->smtp_user));
            $title =  $this->email_encode($title);
            $smtp_name =   $this->email_encode($this->smtp_name);
                         
            $header .= "MIME-Version:1.0\r\n";   
            if($mailtype=="HTML"){   
                $header .= "Content-Type:text/html;charset=utf-8;\r\n";   
            }   
            $header .= "To: ".$to."\r\n";   
            if ($cc != "") {   
                $header .= "Cc: ".$cc."\r\n";   
            }   
            $header .= "From: ".$smtp_name."<".$this->smtp_user.">\r\n";  //lion  
            $header .= "Subject: ".$title."\r\n";   
            $header .= $additional_headers;   
            $header .= "Date: ".date("r")."\r\n";   
            $header .= "X-Mailer:By Redhat (PHP/".phpversion().")\r\n";   
            list($msec, $sec) = explode(" ", microtime());   
            $header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from.">\r\n";   
            $TO = explode(",", $this->strip_comment($to));   

            if ($cc != "") {   
                $TO = array_merge($TO, explode(",", $this->strip_comment($cc)));   
            }   

            if ($bcc != "") {   
                $TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));   
            }   

            $sent = TRUE;   
            foreach ($TO as $rcpt_to) {   
                $rcpt_to = $this->get_address($rcpt_to);   
                if (!$this->smtp_sockopen($rcpt_to)) {   
                    $this->log_write("Error: Cannot send email to ".$rcpt_to."\n");   
                    $sent = FALSE;   
                    continue;   
                }   
                if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $header, $body)) {   
                    $this->log_write("E-mail has been sent to <".$rcpt_to.">\n");   
                } else {   
                    $this->log_write("Error: Cannot send email to <".$rcpt_to.">\n");   
                    $sent = FALSE;   
                }   
                fclose($this->sock);   
                $this->log_write("Disconnected from remote host\n");   
            }     
            return $sent;   
        }
        
        /**
        * 防止中文乱麻
        * 
        * @param mixed $value
        */
        private function email_encode($value){
            return '=?UTF-8?B?'.base64_encode($value).'?=';
        }
        

        /*发送命令*/   
        private function smtp_send($helo, $from, $to, $header, $body = "")   
        {   
            if (!$this->smtp_putcmd("HELO", $helo)) {   
                return $this->smtp_error("sending HELO command");   
            }   
            #auth   
            if($this->smtp_auth){   
                if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->smtp_user))) {   
                    return $this->smtp_error("sending HELO command");   
                }   

                if (!$this->smtp_putcmd("", base64_encode($this->smtp_pass))) {   
                    return $this->smtp_error("sending HELO command");   
                }   
            }   
            #   
            if (!$this->smtp_putcmd("MAIL", "FROM:<".$from.">")) {   
                return $this->smtp_error("sending MAIL FROM command");   
            }   

            if (!$this->smtp_putcmd("RCPT", "TO:<".$to.">")) {   
                return $this->smtp_error("sending RCPT TO command");   
            }   

            if (!$this->smtp_putcmd("DATA")) {   
                return $this->smtp_error("sending DATA command");   
            }   

            if (!$this->smtp_message($header, $body)) {   
                return $this->smtp_error("sending message");   
            }   

            if (!$this->smtp_eom()) {   
                return $this->smtp_error("sending <CR><LF>.<CR><LF> [EOM]");   
            }   

            if (!$this->smtp_putcmd("QUIT")) {   
                return $this->smtp_error("sending QUIT command");   
            }   

            return TRUE;   
        }   

        private function smtp_sockopen($address)   
        {   
            if ($this->smtp_host == "") {   
                return $this->smtp_sockopen_mx($address);   
            } else {   
                return $this->smtp_sockopen_relay();   
            }   
        }   

        private function smtp_sockopen_relay()   
        {   
            $this->log_write("Trying to ".$this->smtp_host.":".$this->smtp_port."\n");   
            $this->sock = @fsockopen($this->smtp_host, $this->smtp_port, $errno, $errstr, $this->time_out);   
            if (!($this->sock && $this->smtp_ok())) {   
                $this->log_write("Error: Cannot connenct to relay host ".$this->smtp_host."\n");   
                $this->log_write("Error: ".$errstr." (".$errno.")\n");   
                return FALSE;   
            }   
            $this->log_write("Connected to relay host ".$this->smtp_host."\n");   
            return TRUE;;   
        }   

        private function smtp_sockopen_mx($address)   
        {   
            $domain = ereg_replace("^.+@([^@]+)$", "\\1", $address);   
            if (!@getmxrr($domain, $MXHOSTS)) {   
                $this->log_write("Error: Cannot resolve MX \"".$domain."\"\n");   
                return FALSE;   
            }   
            foreach ($MXHOSTS as $host) {   
                $this->log_write("Trying to ".$host.":".$this->smtp_port."\n");   
                $this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out);   
                if (!($this->sock && $this->smtp_ok())) {   
                    $this->log_write("Warning: Cannot connect to mx host ".$host."\n");   
                    $this->log_write("Error: ".$errstr." (".$errno.")\n");   
                    continue;   
                }   
                $this->log_write("Connected to mx host ".$host."\n");   
                return TRUE;   
            }   
            $this->log_write("Error: Cannot connect to any mx hosts (".implode(", ", $MXHOSTS).")\n");   
            return FALSE;   
        }   

        private function smtp_message($header, $body)   
        {   
            fputs($this->sock, $header."\r\n".$body);   
            $this->smtp_debug("> ".str_replace("\r\n", "\n"."> ", $header."\n> ".$body."\n> "));   

            return TRUE;   
        }   

        private function smtp_eom()   
        {   
            fputs($this->sock, "\r\n.\r\n");   
            $this->smtp_debug(". [EOM]\n");   

            return $this->smtp_ok();   
        }   

        private function smtp_ok()   
        {   
            $response = str_replace("\r\n", "", fgets($this->sock, 512));   
            $this->smtp_debug($response."\n");   

            if (!ereg("^[23]", $response)) {   
                fputs($this->sock, "QUIT\r\n");   
                fgets($this->sock, 512);   
                $this->log_write("Error: Remote host returned \"".$response."\"\n");   
                return FALSE;   
            }   
            return TRUE;   
        }   

        private function smtp_putcmd($cmd, $arg = "")   
        {   
            if ($arg != "") {   
                if($cmd=="") $cmd = $arg;   
                else $cmd = $cmd." ".$arg;   
            }   

            fputs($this->sock, $cmd."\r\n");   
            $this->smtp_debug("> ".$cmd."\n");   

            return $this->smtp_ok();   
        }   

        private function smtp_error($string)   
        {   
            $this->log_write("Error: Error occurred while ".$string.".\n");   
            return false;   
        }   

        private function log_write($message)   
        {   
            if(!$this->log_open){
                return true;
            }

            $this->smtp_debug($message);   

            if ($this->log_file == "") {   
                return true;   
            }   

            $message = date("M d H:i:s ").get_current_user()."[".getmypid()."]: ".$message;   
            if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a"))) {   
                $this->smtp_debug("Warning: Cannot open log file \"".$this->log_file."\"\n");   
                return false;   
            }   
            flock($fp, LOCK_EX);   
            fputs($fp, $message);   
            fclose($fp);   

            return true;   
        }   

        private function strip_comment($address)   
        {   
            $comment = "\\([^()]*\\)";   
            while (ereg($comment, $address)) {   
                $address = ereg_replace($comment, "", $address);   
            }   

            return $address;   
        }   

        private function get_address($address)   
        {   
            $address = ereg_replace("([ \t\r\n])+", "", $address);   
            $address = ereg_replace("^.*<(.+)>.*$", "\\1", $address);   

            return $address;   
        }   

        private function smtp_debug($message)   
        {   
            if ($this->debug) {   
                echo $message."<br>";   
            }   
        }   

        private function get_attach_type($image_tag) { //   

            $filedata = array();   

            $img_file_con=fopen($image_tag,"r");   
            unset($image_data);   
            while ($tem_buffer=AddSlashes(fread($img_file_con,filesize($image_tag))))   
                $image_data.=$tem_buffer;   
            fclose($img_file_con);   

            $filedata['context'] = $image_data;   
            $filedata['filename']= basename($image_tag);   
            $extension=substr($image_tag,strrpos($image_tag,"."),strlen($image_tag)-strrpos($image_tag,"."));   
            switch($extension){   
                case ".gif":   
                    $filedata['type'] = "image/gif";   
                    break;   
                case ".gz":   
                    $filedata['type'] = "application/x-gzip";   
                    break;   
                case ".htm":   
                    $filedata['type'] = "text/html";   
                    break;   
                case ".html":   
                    $filedata['type'] = "text/html";   
                    break;   
                case ".jpg":   
                    $filedata['type'] = "image/jpeg";   
                    break;   
                case ".tar":   
                    $filedata['type'] = "application/x-tar";   
                    break;   
                case ".txt":   
                    $filedata['type'] = "text/plain";   
                    break;   
                case ".zip":   
                    $filedata['type'] = "application/zip";   
                    break;   
                default:   
                    $filedata['type'] = "application/octet-stream";   
                    break;   
            }   


            return $filedata;   
        }   

    }
?>
